package com.yujn.springsecurityactual.config;

import cn.hutool.json.JSONUtil;
import com.sun.org.apache.regexp.internal.RE;
import com.yujn.springsecurityactual.bean.Result;
import com.yujn.springsecurityactual.filter.VerificationCodeFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.session.HttpSessionEventPublisher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @description: web seucurity config
 * @author: Yujn
 * @create: 2021-03-14 11:00
 **/
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled=true)// 开启注解权限控制
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthenticationSuccessHandler myAuthenticationSuccessHandler;
    @Autowired
    AuthenticationFailureHandler myAuthenticationFailureHandler;
    @Autowired
    LogoutSuccessHandler myLogoutSuccessHandler;


    /**
     * 配置事件源，清除注销session
     * @param
     * @return
     * @author yujn
     * @date 2021/3/24 15:09
     */
    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher(){
        return new HttpSessionEventPublisher();
    }


//    @Bean
//    public PasswordEncoder passwordEncoder(){
//        return new BCryptPasswordEncoder();
//    }
//
//
//    @Bean
//    public UserDetailsService users() {
//        UserDetails user = User.builder()
//                .username("user")
//                .password(new BCryptPasswordEncoder().encode("123"))
//                .roles("USER")
//                .build();
//
//        UserDetails admin = User.builder()
//                .username("admin")
//                .password(new BCryptPasswordEncoder().encode("123"))
//                .roles("ADMIN","USER")
//                .build();
//        return new InMemoryUserDetailsManager(user,admin);
//    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                    .antMatchers("/admin/api/**").hasRole("ADMIN")
                    .antMatchers("/app/api/**","/captcha/**").permitAll()
                    .antMatchers("/user/api/**").hasRole("USER")
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/myLogin.html")
                    .loginProcessingUrl("/login")
                    .permitAll()
                    .successHandler(myAuthenticationSuccessHandler)
                    .failureHandler(myAuthenticationFailureHandler)
                    .and()
                .logout()
                    // 指定接收注销请求的路由
                    .logoutUrl("/myLogout")
                    // 注销成功，重定向到改路径
                    .logoutSuccessUrl("/myLogin.html")
                    // 注销成功的处理方式，不同于logoutSuccessUrl的重定向，logoutSuccessHandler更加灵活
                    .logoutSuccessHandler(myLogoutSuccessHandler)
                    // 使该用户的HtppSession失效
                    .invalidateHttpSession(true)
                    .and()
                .csrf().disable()
                .sessionManagement()
                    .maximumSessions(1)
                    .maxSessionsPreventsLogin(true);

        // 将过滤其添加在UsernamePasswordAuthenticationFilter 之前
        http.addFilterBefore(new VerificationCodeFilter(), UsernamePasswordAuthenticationFilter.class);
    }


}
